package com.oldbook.quartz.task;


import com.oldbook.common.core.domain.entity.SysUser;
import com.oldbook.common.enums.OrderStatusEnum;
import com.oldbook.manage.domain.Order;
import com.oldbook.manage.service.IOrderService;
import com.oldbook.system.service.impl.SysUserServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.List;

/**
 * 信用分定时任务处理器
 *
 * @author DELL
 */
@Slf4j
@Component("CreditScoreTask")
public class CreditScoreTask {
    @Autowired
    private IOrderService orderService;
    @Autowired
    private SysUserServiceImpl userService;

    /**
     * 执行超期未归还订单的信用分扣减任务（修正版）
     *
     * <p><b>改进说明：</b>
     * <ol>
     *   <li>新增每日渐进式扣分机制，避免一次性扣除</li>
     *   <li>修正状态过滤逻辑，准确识别待处理订单</li>
     *   <li>增加信用分下限保护（不低于0分）</li>
     * </ol>
     */
    @Transactional(rollbackFor = Exception.class)
    public void deductCreditForOverdueOrders() {
        /* 精确获取待处理逾期订单 */
        List<Order> overdueOrders = orderService.getOverdueOrders();
        log.info("开始执行渐进式信用分扣减任务，待处理订单数：{}", overdueOrders.size());

        for (Order order : overdueOrders) {
            /* 状态有效性验证 */
            log.debug("获取枚举值{}",OrderStatusEnum.IN_OVERDUE.getCode());
            if ((!OrderStatusEnum.IN_OVERDUE.getCode().equals(order.getStatus()))) {
                log.debug("跳过已处理订单[{}]，当前状态：{}", order.getOrderId(), order.getStatus());
                continue;
            }

            /* 渐进式逾期计算 */
            LocalDate lastCalcDate = order.getLastDeductionDate() != null ?
                    order.getLastDeductionDate() :
                    order.getDueDate().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();

            // 使用 end date 包含当天的方式计算
            long actualDays = ChronoUnit.DAYS.between(
                    lastCalcDate,
                    LocalDate.now().plusDays(1) // 包含当天
            );
            if(actualDays < 1) {
                continue;
            }

            /* 安全信用分操作 */

            log.info("日期计算 | 最后扣分日:{} | 当前日期:{} | 实际天数:{}",
                    lastCalcDate, LocalDate.now(), actualDays);


            int currentCredit = userService.selectUserByStudentId(order.getStudentId()).getCreditScore();

            // 在扣分操作前添加校验日志

            log.debug("当前用户[{}]信用分：[{}]", order.getStudentId(), currentCredit);
            // 计算实际扣分值，避免一次性扣分
            int safeDeduction = Math.min((int)actualDays * 1, currentCredit); // 每日1分且不超过当前分数
            log.info("准备扣分 | 用户:{} | 当前分:{} | 应扣分:{}",
                    order.getStudentId(), currentCredit, safeDeduction);
            int finalCredit = Math.max(currentCredit - safeDeduction, 0);

            // 在扣分前检查最后扣分时间
            if (order.getLastDeductionDate() != null &&
                    order.getLastDeductionDate().isAfter(LocalDate.now().minusDays(1))) {
                log.info("订单[{}]今日已扣分，跳过", order.getOrderId());
                continue;
            }

            /* 执行更新操作 */
            userService.deductCreditScore(order.getStudentId(), safeDeduction);
            orderService.updateOrderStatus(order.getOrderId(), "2");
            orderService.updateLastDeductionDate(LocalDate.now(),order.getOrderId());

            log.info("订单[{}]渐进扣分 | 逾期天数: {} | 扣分值: {} | 最终信用分: {}",
                    order.getOrderId(), actualDays, safeDeduction, finalCredit);

            // 在更新操作后添加结果验证
            SysUser updatedUser = userService.selectUserByStudentId(order.getStudentId());
            log.info("扣分验证 | 用户:{} | 更新后分数:{}", order.getStudentId(), updatedUser.getCreditScore());
        }


    }
}
